package com.cencat.route.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cencat.route.entity.Dispatch;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 调度信息数据访问层
 * 提供调度信息的数据库操作接口
 * 
 * @author cencat
 * @version 1.0
 * @since 2024-01-01
 */
@Mapper
public interface DispatchMapper extends BaseMapper<Dispatch> {

    /**
     * 分页查询调度信息
     */
    Page<Dispatch> selectDispatchPage(Page<Dispatch> page, @Param("dispatchCode") String dispatchCode, 
                                     @Param("routeId") Long routeId, @Param("driverId") Long driverId,
                                     @Param("status") String status);

    /**
     * 条件查询调度信息
     */
    List<Dispatch> searchDispatches(@Param("conditions") Map<String, Object> conditions);

    /**
     * 根据调度编号查询调度
     */
    @Select("SELECT * FROM dispatch WHERE dispatch_code = #{dispatchCode} AND deleted = 0")
    Dispatch selectByDispatchCode(@Param("dispatchCode") String dispatchCode);

    /**
     * 根据路线ID查询调度列表
     */
    @Select("SELECT * FROM dispatch WHERE route_id = #{routeId} AND deleted = 0")
    List<Dispatch> selectByRouteId(@Param("routeId") Long routeId);

    /**
     * 根据司机ID查询调度列表
     */
    @Select("SELECT * FROM dispatch WHERE driver_id = #{driverId} AND deleted = 0")
    List<Dispatch> selectByDriverId(@Param("driverId") Long driverId);

    /**
     * 根据车辆ID查询调度列表
     */
    @Select("SELECT * FROM dispatch WHERE vehicle_id = #{vehicleId} AND deleted = 0")
    List<Dispatch> selectByVehicleId(@Param("vehicleId") Long vehicleId);

    /**
     * 根据状态查询调度列表
     */
    @Select("SELECT * FROM dispatch WHERE status = #{status} AND deleted = 0")
    List<Dispatch> selectByStatus(@Param("status") String status);

    /**
     * 根据调度类型查询调度列表
     */
    @Select("SELECT * FROM dispatch WHERE dispatch_type = #{dispatchType} AND deleted = 0")
    List<Dispatch> selectByDispatchType(@Param("dispatchType") String dispatchType);

    /**
     * 批量更新调度状态
     */
    @Update("<script>" +
            "UPDATE dispatch SET status = #{status}, updated_time = NOW() " +
            "WHERE id IN " +
            "<foreach collection='ids' item='id' open='(' separator=',' close=')'>" +
            "#{id}" +
            "</foreach>" +
            "</script>")
    int batchUpdateStatus(@Param("ids") List<Long> ids, @Param("status") String status);

    /**
     * 批量更新调度优先级
     */
    @Update("<script>" +
            "UPDATE dispatch SET priority = #{priority}, updated_time = NOW() " +
            "WHERE id IN " +
            "<foreach collection='ids' item='id' open='(' separator=',' close=')'>" +
            "#{id}" +
            "</foreach>" +
            "</script>")
    int batchUpdatePriority(@Param("ids") List<Long> ids, @Param("priority") Integer priority);

    /**
     * 批量分配司机
     */
    @Update("<script>" +
            "UPDATE dispatch SET driver_id = #{driverId}, updated_time = NOW() " +
            "WHERE id IN " +
            "<foreach collection='ids' item='id' open='(' separator=',' close=')'>" +
            "#{id}" +
            "</foreach>" +
            "</script>")
    int batchAssignDriver(@Param("ids") List<Long> ids, @Param("driverId") Long driverId);

    /**
     * 批量分配车辆
     */
    @Update("<script>" +
            "UPDATE dispatch SET vehicle_id = #{vehicleId}, updated_time = NOW() " +
            "WHERE id IN " +
            "<foreach collection='ids' item='id' open='(' separator=',' close=')'>" +
            "#{id}" +
            "</foreach>" +
            "</script>")
    int batchAssignVehicle(@Param("ids") List<Long> ids, @Param("vehicleId") Long vehicleId);

    /**
     * 获取调度统计分析
     */
    Map<String, Object> getDispatchStatistics(@Param("startTime") LocalDateTime startTime, 
                                             @Param("endTime") LocalDateTime endTime);

    /**
     * 智能匹配调度
     */
    List<Dispatch> intelligentMatchDispatches(@Param("conditions") Map<String, Object> conditions);

    /**
     * 查询待调度任务
     */
    @Select("SELECT * FROM dispatch WHERE status = 'PENDING' AND deleted = 0 ORDER BY priority DESC, created_time ASC")
    List<Dispatch> selectPendingDispatches();

    /**
     * 查询进行中调度
     */
    @Select("SELECT * FROM dispatch WHERE status = 'IN_PROGRESS' AND deleted = 0")
    List<Dispatch> selectInProgressDispatches();

    /**
     * 查询已完成调度
     */
    @Select("SELECT * FROM dispatch WHERE status = 'COMPLETED' AND deleted = 0")
    List<Dispatch> selectCompletedDispatches();

    /**
     * 查询已取消调度
     */
    @Select("SELECT * FROM dispatch WHERE status = 'CANCELLED' AND deleted = 0")
    List<Dispatch> selectCancelledDispatches();

    /**
     * 检查调度是否存在
     */
    @Select("SELECT COUNT(*) > 0 FROM dispatch WHERE dispatch_code = #{dispatchCode} AND deleted = 0")
    boolean checkDispatchExists(@Param("dispatchCode") String dispatchCode);

    /**
     * 调度开始
     */
    @Update("UPDATE dispatch SET status = 'IN_PROGRESS', start_time = NOW(), updated_time = NOW() WHERE id = #{id}")
    int startDispatch(@Param("id") Long id);

    /**
     * 调度完成
     */
    @Update("UPDATE dispatch SET status = 'COMPLETED', end_time = NOW(), updated_time = NOW() WHERE id = #{id}")
    int completeDispatch(@Param("id") Long id);

    /**
     * 调度取消
     */
    @Update("UPDATE dispatch SET status = 'CANCELLED', cancel_time = NOW(), updated_time = NOW() WHERE id = #{id}")
    int cancelDispatch(@Param("id") Long id);

    /**
     * 调度暂停
     */
    @Update("UPDATE dispatch SET status = 'PAUSED', updated_time = NOW() WHERE id = #{id}")
    int pauseDispatch(@Param("id") Long id);

    /**
     * 调度恢复
     */
    @Update("UPDATE dispatch SET status = 'IN_PROGRESS', updated_time = NOW() WHERE id = #{id}")
    int resumeDispatch(@Param("id") Long id);

    /**
     * 更新调度进度
     */
    @Update("UPDATE dispatch SET progress = #{progress}, updated_time = NOW() WHERE id = #{id}")
    int updateProgress(@Param("id") Long id, @Param("progress") BigDecimal progress);

    /**
     * 获取调度效率统计
     */
    Map<String, Object> getDispatchEfficiencyStatistics(@Param("startTime") LocalDateTime startTime, 
                                                       @Param("endTime") LocalDateTime endTime);

    /**
     * 获取司机调度统计
     */
    Map<String, Object> getDriverDispatchStatistics(@Param("driverId") Long driverId, 
                                                   @Param("startTime") LocalDateTime startTime, 
                                                   @Param("endTime") LocalDateTime endTime);

    /**
     * 获取路线调度统计
     */
    Map<String, Object> getRouteDispatchStatistics(@Param("routeId") Long routeId, 
                                                  @Param("startTime") LocalDateTime startTime, 
                                                  @Param("endTime") LocalDateTime endTime);

    /**
     * 根据时间范围查询调度
     */
    List<Dispatch> selectByTimeRange(@Param("startTime") LocalDateTime startTime, 
                                    @Param("endTime") LocalDateTime endTime);

    /**
     * 根据优先级查询调度
     */
    List<Dispatch> selectByPriority(@Param("minPriority") Integer minPriority, 
                                   @Param("maxPriority") Integer maxPriority);

    /**
     * 查询紧急调度
     */
    @Select("SELECT * FROM dispatch WHERE urgent = 1 AND deleted = 0 ORDER BY priority DESC")
    List<Dispatch> selectUrgentDispatches();

    /**
     * 查询延期调度
     */
    @Select("SELECT * FROM dispatch WHERE status IN ('PENDING', 'IN_PROGRESS') AND planned_end_time < NOW() AND deleted = 0")
    List<Dispatch> selectOverdueDispatches();

    /**
     * 获取调度任务管理统计
     */
    Map<String, Object> getDispatchTaskStatistics();

    /**
     * 自动分配最优司机
     */
    Long autoAssignOptimalDriver(@Param("dispatchId") Long dispatchId, @Param("conditions") Map<String, Object> conditions);

    /**
     * 自动分配最优车辆
     */
    Long autoAssignOptimalVehicle(@Param("dispatchId") Long dispatchId, @Param("conditions") Map<String, Object> conditions);
}